package com.dana1.nos.old.impl;

import java.lang.reflect.Proxy;
import java.util.AbstractCollection;
import java.util.Iterator;

import com.dana1.nos.old.ObjectKey;
import com.dana1.nos.old.ObjectService;
import com.dana1.nos.old.ServiceObject;

public class ProxyMMCollection<T extends ServiceObject> extends AbstractCollection<T>
{
	private ObjectService objectService;
	private ObjectKey<? extends ServiceObject> ownerKey;
	private String relationName;
	private boolean autoInsertServiceObjects = false;
	
	public ProxyMMCollection(ObjectService objectService, ObjectKey<? extends ServiceObject> ownerKey, String relationName, boolean autoInsertServiceObjects)
	{
		this.objectService = objectService;
		this.ownerKey = ownerKey;
		this.relationName = relationName;
		this.autoInsertServiceObjects = autoInsertServiceObjects;
	}

	public ObjectKey<? extends ServiceObject> getOwnerKey()
	{
		return ownerKey;
	}
	public String getRelationName()
	{
		return relationName;
	}
	public boolean isAutoInsertServiceObjects()
	{
		return autoInsertServiceObjects;
	}
	public ObjectService getObjectService()
	{
		return objectService;
	}
	
	@Override
	public Iterator<T> iterator()
	{
		return new Iterator<T>() {
			private Iterator<ObjectKey<?>> iObjs = objectService.retrieveMM(ownerKey, relationName).iterator();
			private ObjectKey<T> current = null;
			@Override
			public boolean hasNext()
			{
				return iObjs.hasNext();
			}
			@SuppressWarnings("unchecked")
			@Override
			public T next()
			{
				current=(ObjectKey<T>) iObjs.next();
				return objectService.retrieve(current);
			}
			@Override
			public void remove()
			{
				objectService.removeMM(ownerKey, relationName, current);
			}
		};
	}
	@Override
	public int size()
	{
		return objectService.retrieveMM(ownerKey, relationName).size();
	}
	@Override
	public boolean add(T e)
	{
		return objectService.addMM(ownerKey, relationName, maybeInsertReferencedObject(e));
	}

	
	private ObjectKey<?> maybeInsertReferencedObject(Object arg)
	{
		ObjectKey<?> key = null;
		if (arg!=null)
		{
			if (!((ServiceObjectInvocationHandler<?>)Proxy.getInvocationHandler(arg)).isConnected())
				if (isAutoInsertServiceObjects())
					key=objectService.insert((ServiceObject)arg);
				else
					throw new UnsupportedOperationException("Cannot add an object that has not been inserted");
			key = objectService.objectKey((ServiceObject)arg);
		}
		return key;
	}

}
